Skip to content

Revive TracingMacros and @Traced #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

ktoso
Copy link
Member

@ktoso ktoso commented Aug 4, 2025

This brings back, and will polish up a bit the @Traced macro that was initially pitched over here #157 by @porglezomp.

I'm signing up for long term maintenance of the macro, and we need to post about expectations and rules of macro use/adoption in libraries, but we should not outright ban them.


This provides a @Traced macro which adds a tracing span around the body of the function. This macro allows customizing the operationName, the context, and the kind of the span, same as the withSpan function. It also exposes the span itself into the scope of the function, with a customizable name.

This doesn't attempt to support automatically adding parameters as attributes, because the scoping rules of attached macros aren't very amenable to controlling that. That could be added in the future if it's judged necessary.

Examples:

@Traced("preheat oven")
func preheatOven(temperature: Int) async throws -> Oven {
    span.attributes["oven.targetTemperature"] = temperature
    await sleep(for: .seconds(6))
    return Oven()
}

expands to:

func preheatOven(temperature: Int) async throws -> Oven {
    withSpan("preheat oven") { span in
        span.attributes["oven.targetTemperature"] = temperature
        await sleep(for: .seconds(6))
        return Oven()
    }
}

Resolves #125

porglezomp and others added 9 commits August 5, 2025 07:36
This is defined as a separate product so that users who don't want to
pay the compile-time cost of macros don't have to use it, you opt-in to
that cost by depending on the TracingMacros module.

The @Traced macro is only available in Swift 6.0 compilers since
function body macros were introduced in Swift 6.0.

This adds minimum OS versions for Apple platforms in order to be able to
depend on SwiftSyntax. This applies to the whole package since there are
no per-target platform specifications. Most notably: This raises the
macOS minimum deployment target from the (implicit) 10.13 to 10.15.
Based on the effects signature of the attached function we apply
try/await as appropriate. But, if the function is async/throws but those
effects aren't actually used in the function body, this causes a new
warning because the closure isn't inferred to be async and/or throws. To
avoid those warnings, we also apply matching effects specifiers to the
withSpan closure.
First, allow overriding the regular parameters of the withSpan call:
setting the operationName, the context, and the kind. If it's not
specified, it's not passed to the function, which means the function
remains the source of truth for default arguments.

Also allow overriding the span name, which controls the variable binding
in the closure body. This is primarily useful for avoiding shadowing an
outer "span" variable.
**Motivation:**

We want to allow richer customization of the operation name in the
`@Traced` macro, in particular the difference between the different ways
you can view a function name.

**Modifications:**

- Add a TracedOperationName type that represents the kinds of operation
  names we want to support.
- Change the `@Traced` macro interface and expansion to use the new
  operation name type.

**Result:**

Now you can write `@Traced(.baseName)`, `@Traced(.fullName)` as well as
`@Traced("custom name here")`, giving more flexibility between types of
operation names.
@ktoso
Copy link
Member Author

ktoso commented Aug 4, 2025

Heh, I forgot about the trouble with platform bump here... We may put it into a separate package -- we could do a new package that is specifically just swift-distributed-tracing-macros.

@ktoso ktoso marked this pull request as draft August 4, 2025 23:27
@czechboy0
Copy link
Contributor

Have we considered putting the macros into the main module behind an opt-in trait, and the trait only being defined in a 6.1-specific manifest?

Having to add an explicit product dependency and then a separate import seems like a less ergonomic solution than a trait that you enable in one place, and then in your whole codebase you can use the macro with your existing import Tracing import. cc @FranzBusch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Offer @traced macro when macros gain function body replacement capabilities
3 participants